function MonthView(month) {
    this._month = month;
    this._daysWithMonthTitle = [month.firstDayInMonth().addDays(-1), month.firstDayInMonth(), month.firstDayInMonth().addMonths(1)];
}

MonthView.prototype = {
    updateDay: function(day) {
        var dayTd = $(this._table).find('div[id$=' + day.getDate().toString('yyyy-MM-dd') + ']').parent();
        var dayDom = this._createDay(day);
        dayTd.html(dayDom.html());
    },
    render: function() {
        var me = this;

        this._table = this._createContainer();
        this._table.append(this._create_week_bar());

        var row;
        me._month.getFullDays().foreach(function(day, index) {
            if (me._isFirstDayOfWeek(index)) {
                row = $('<tr/>');
                me._table.append(row);
            }
            row.append(me._createDay(day));
        });
        return this._table;
    },
    _createDay: function(day) {
        var date = day.getDate();
        var renderMonthTitle = date.inDates(this._daysWithMonthTitle);
        var isMissingTravelDay = this._month.isMissingTravelDay(date);
        var dayInCurrentMonth = day.isInMonth(this._month.getYearMonth());
        var dayView = new DayView(day, dayInCurrentMonth, renderMonthTitle, isMissingTravelDay);
        return dayView.render();
    },

    _createContainer: function() {
        return $('<table id="calendar-month-table" class="calendar-body"/>');
    },

    _create_week_bar: function() {
        var bar = $('<tr id="calendar_week_bar"/>');
        CalendarViewBody.getWeekShortTitles().foreach(function(title) {
            bar.append("<th>" + title + "</th>");
        });
        return bar;
    },

    _isFirstDayOfWeek: function(index) {
        return index % 7 == 0;
    }
};